import { Injector, ViewChild } from '@angular/core';
import { STChange, STColumn, STComponent, STData, STError, STPage, STReq, STRequestOptions, STRes } from '@delon/abc/st';
import { SFSchema, SFSchemaEnumType, SFUISchema } from '@delon/form';
import { _HttpClient } from '@delon/theme';
import { NzDrawerComponent, NzDrawerService } from 'ng-zorro-antd/drawer';
import { NzModalComponent, NzModalService, } from 'ng-zorro-antd/modal';


import { AjaxResult, ItcoreImport, ListSortDirection, PageCondition, PageRequest, SortCondition } from '../itcore.model';
import { AlainService } from '../services/alain.service';
import { ItcoreSTColumn } from '../services/alain.types';
import { itcoreService } from '../services/itcore.service';

export abstract class STComponentBase {
  moduleName: string;
  areaName = 'admin/'; // 默认为 admin 其他需重写
  protected isUserDrawer = false;
  // URL
  readUrl: string;
  createUrl: string;
  updateUrl: string;
  deleteUrl: string;
  importUrl: string;
  exportUrl: string;
  exportFileName: string;

  // 表格属性
  columns: ItcoreSTColumn[];
  request: PageRequest;
  req: STReq;
  res: STRes;
  page: STPage;
  @ViewChild('st', { static: false }) st: STComponent;

  // 编辑属性
  schema: SFSchema;
  ui: SFUISchema;
  editRow: STData;
  editTitle = '编辑';
  @ViewChild('modal', { static: false }) editModal: NzModalComponent;

  // 抽屉
  @ViewChild('drawer', { static: false }) editDrawer: NzDrawerComponent;




  itcore: itcoreService;
  alain: AlainService;
  selecteds: STData[] = [];
  // 当前操作状态 1：init 2：create 3:edit
  private currentOperateStatus: number;

  // 提示模态框
  itcoreModal: NzModalService;
  // 导入配置
  public importOption: ItcoreImport;

  constructor(injector: Injector) {
    this.itcore = injector.get(itcoreService);
    this.alain = injector.get(AlainService);
    this.itcoreModal = injector.get(NzModalService);
  }

  get http(): _HttpClient {
    return this.itcore.http;
  }

  protected InitBase() {
    this.readUrl = `api/${this.areaName}${this.moduleName}/read`;
    this.createUrl = `api/${this.areaName}${this.moduleName}/create`;
    this.updateUrl = `api/${this.areaName}${this.moduleName}/update`;
    this.deleteUrl = `api/${this.areaName}${this.moduleName}/delete`;

    this.exportUrl = `api/${this.moduleName}/Export`;
    this.importUrl = `api/${this.moduleName}/Import`;
    this.importOption = new ItcoreImport(this.importUrl, '导入', 'MIME/vnd.ms-excel');

    this.currentOperateStatus = 1;
    this.request = new PageRequest();
    this.columns = this.GetSTColumns();
    this.req = this.GetSTReq(this.request);
    this.res = this.GetSTRes();
    this.page = this.GetSTPage();

    this.schema = this.GetSFSchema();
    this.ui = this.GetSFUISchema();
  }

  // #region 表格

  /**
   * 重写以获取表格的列设置 Columns
   */
  protected abstract GetSTColumns(): ItcoreSTColumn[];

  protected GetSTReq(request: PageRequest): STReq {
    return this.alain.GetSTReq(request, (opt) => this.RequestProcess(opt));
  }

  protected GetSTRes(): STRes {

    return this.alain.GetSTRes((data: STData[]) => this.ResponseDataProcess(data));
  }

  protected GetSTPage(): STPage {
    return this.alain.GetSTPage();
  }

  protected RequestProcess(opt: STRequestOptions): STRequestOptions {
    return this.alain.RequestProcess(opt, (field) => this.ReplaceFieldName(field));
  }

  protected ResponseDataProcess(data: STData[]): STData[] {
    return data;
  }

  protected ReplaceFieldName(field: string): string {
    return field;
  }

  search(request: PageRequest) {
    if (!request) {
      return;
    }
    this.req.body = request;
    this.st.reload();
  }

  change(value: STChange) {
    if (value.type === 'checkbox') {
      this.selecteds = value.checkbox;
    } else if (value.type === 'radio') {
      this.selecteds = [value.radio];
    }
  }

  error(value: STError) {
    console.error(value);
  }

  // #endregion

  // #region 编辑

  /**
   * 默认由列配置 `ItcoreSTColumn[]` 来生成SFSchema，不需要可以重写定义自己的SFSchema
   */
  protected GetSFSchema(): SFSchema {
    const schema: SFSchema = { properties: this.ColumnsToSchemas(this.columns), required: this.columns[0].required };
    return schema;
  }

  // 拓展列用于 数据表格没有，新增编辑能够操作的
  protected GetExpandSFSchema(): ItcoreSTColumn[] {
    return [];
  }

  protected ColumnsToSchemas(columns: ItcoreSTColumn[]): { [key: string]: SFSchema } {

    // 增加 (!this.currentOperateStatus && column.IsHideEdit) 在编辑的时候隐藏这一列
    // 增加拓展列，新增编辑的
    if (this.currentOperateStatus > 1 && this.GetExpandSFSchema() && this.GetExpandSFSchema().length > 0) {
      columns.push(...this.GetExpandSFSchema());
    }

    // 排序
    columns.sort((a, b) => {
      const val = (a.sortNumber || 0) - (b.sortNumber || 0);
      return val;
    });

    const properties: { [key: string]: SFSchema } = {};
    for (const column of columns) {
      if (!column.index || !column.editable || column.buttons || (this.currentOperateStatus === 3 && column.IsHideEdit)) {
        continue;
      }
      const schema: SFSchema = this.alain.ToSFSchema(column);
      properties[column.index as string] = schema;
    }
    return properties;
  }

  protected GetSFUISchema(): SFUISchema {
    const ui: SFUISchema = {};
    return ui;
  }

  protected toEnum(items: { id: number; text: string }[]): SFSchemaEnumType[] {
    return items.map((item) => {
      const e: SFSchemaEnumType = { value: item.id, label: item.text };
      return e;
    });
  }

  create() {
    if ((!this.isUserDrawer && !this.editModal) || (this.isUserDrawer && !this.editDrawer)) {
      return;
    }
    this.currentOperateStatus = 2;
    this.schema = this.GetSFSchema();
    this.ui = this.GetSFUISchema();
    this.editRow = {};
    this.editTitle = '新增';

    if (this.isUserDrawer) {
      this.editDrawer.open();
    } else {
      this.editModal.open();
    }

  }

  edit(row: STData) {
    if ((!this.isUserDrawer && !this.editModal) || (this.isUserDrawer && !this.editDrawer)) {
      return;
    }
    this.currentOperateStatus = 3;
    this.schema = this.GetSFSchema();

    this.ui = this.GetSFUISchema();
    this.editRow = row;
    this.editTitle = '编辑';

    if (this.isUserDrawer) {

      this.editDrawer.open();
    } else {
      this.editModal.open();
    }
  }

  close() {
    if ((!this.isUserDrawer && !this.editModal) || (this.isUserDrawer && !this.editDrawer)) {
      return;
    }
    if (this.isUserDrawer) {
      this.editDrawer.close();
    } else {
      this.editModal.destroy();
    }
  }

  save(value: STData) {
    const url = value.Id ? this.updateUrl : this.createUrl;
    this.http
      .post<AjaxResult>(url, [value])
      .subscribe((result) => {
        this.itcore.ajaxResult(result, () => {
          this.st.reload();
          this.close();
        });
      });
  }

  delete(value: STData) {
    if (!value) {
      return;
    }
    this.http
      .post<AjaxResult>(this.deleteUrl, [value.Id])
      .subscribe((result) => {
        this.itcore.ajaxResult(result, () => {
          this.st.reload();
        });
      });
  }

  // #endregion

  //#region  导出
  /**
   * 导出通用方法
   */
  export() {
    this.itcoreModal.confirm({
      nzTitle: '确认提醒',
      nzContent: '请确认是否导出？',
      nzOnOk: () =>
        new Promise((resolve, reject) => {
          this.http.post(this.exportUrl, this.req.body, null, { responseType: 'blob' }).subscribe((result) => {
            this.itcore.download(this.exportFileName + '.xls', result);
            setTimeout(Math.random() > 0.5 ? resolve : reject, 1000);
          });
        }).catch(() => console.log('Oops errors!')),
    });
  }

  //#endregion
}
